package com.tencent.tmm.knoi.sample

import com.tencent.tmm.knoi.annotation.Hidden
import com.tencent.tmm.knoi.annotation.ServiceProvider
import com.tencent.tmm.knoi.converter.ktValueToJSValue
import com.tencent.tmm.knoi.getEnv
import com.tencent.tmm.knoi.logger.info
import com.tencent.tmm.knoi.type.ArrayBuffer
import com.tencent.tmm.knoi.type.JSValue
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.set
import platform.posix.uint8_tVar
import kotlin.native.runtime.NativeRuntimeApi
import kotlin.reflect.KClass
import kotlin.random.Random  // 添加 Random 导入
private var logImpl: JSValue? = null
private var status = true

@ServiceProvider(bind = TestServiceBApi::class, singleton = false)
open class TestServiceB : TestServiceBApi {
    init {
        info("TestServiceB init.")
    }
    fun getStudentWithJSValue(): JSValue {
        val student = Student(
            name = "张三",
            age = 20,
            address = Address(
                city = "北京",
                street = "中关村大街",
                zipCode = "100080"
            ),
            scores = listOf(90.5, 85.0, 92.3),
            tags = mapOf(
                "grade" to "大二",
                "major" to "计算机科学"
            )
        )

        // 一行代码完成转换！
        return student.toJSValue()
    }

    fun getSchoolInfo(): JSValue {
        val school = School(
            name = "清华大学",
            address = Address("北京", "清华园", "100084"),
            students = listOf(
                Student(
                    "张三",
                    20,
                    Address("北京", "中关村", "100080"),
                    listOf(90.0, 88.5),
                    mapOf("grade" to "大二")
                ),
                Student(
                    "李四",
                    21,
                    Address("上海", "浦东", "200120"),
                    listOf(95.0, 89.0),
                    mapOf("grade" to "大三")
                )
            ),
            classes = mapOf(
                "CS101" to listOf(
                    Student(
                        "王五",
                        19,
                        Address("广州", "天河", "510000"),
                        listOf(86.0, 91.5),
                        mapOf("grade" to "大一")
                    )
                )
            )
        )

        // 复杂对象也是一行代码搞定！
        return school.toJSValue()
    }



    // 返回包含嵌套对象的 Student JSValue
//    fun getStudentWithJSValue(): JSValue {
//        // 创建地址对象
//        val address = Address(city = "北京", street = "中关村大街")
//
//        // 创建学生对象
//        val student = Student(name = "张三", age = 20, address = address)
//
//        // 构建 JSValue
//        val jsValue = JSValue.createJSObject()
//        jsValue["name"] = JSValue.createJSValue(student.name)
//        jsValue["age"] = JSValue.createJSValue(student.age)
//
//        // 构建嵌套的 Address JSValue
//        val addressJSValue = JSValue.createJSObject()
//        addressJSValue["city"] = JSValue.createJSValue(student.address.city)
//        addressJSValue["street"] = JSValue.createJSValue(student.address.street)
//
//        // 将 address 对象添加到 student 中
//        jsValue["address"] = addressJSValue
//
//        return jsValue
//    }

    // ========== 新增高级测试方法 ==========

    // 测试1：超深层嵌套结构 - University包含Schools包含Students
    fun getUniversityComplex(): JSValue {
        val beijingAddress = Address("北京", "海淀区", "100080")
        val shanghaiAddress = Address("上海", "浦东新区", "200120")

        val topStudent1 = Student(
            name = "学霸张",
            age = 22,
            address = beijingAddress,
            scores = listOf(98.5, 99.0, 97.8, 99.5),
            tags = mapOf(
                "rank" to "1",
                "scholarship" to "国家奖学金",
                "research" to "AI方向"
            )
        )

        val school1 = School(
            name = "计算机学院",
            address = beijingAddress,
            students = listOf(topStudent1),
            classes = mapOf(
                "AI101" to listOf(topStudent1),
                "ML202" to listOf(
                    Student(
                        "李明",
                        21,
                        shanghaiAddress,
                        listOf(95.0, 94.5, 96.0),
                        mapOf("major" to "机器学习")
                    )
                )
            )
        )

        val university = University(
            name = "顶级大学",
            schools = listOf(school1),
            partnerships = mapOf(
                "国际合作" to listOf(school1),
                "产学研" to listOf(school1)
            ),
            statistics = Statistics(
                totalStudents = 5000,
                averageScore = 85.5,
                scoreDistribution = mapOf(
                    "90-100" to 500,
                    "80-89" to 2000,
                    "70-79" to 1500,
                    "60-69" to 800,
                    "<60" to 200
                ),
                topStudents = listOf(topStudent1)
            )
        )

        return university.toJSValue()
    }
    // 测试2：大数据量测试 - 生成大量学生数据
    // 测试2：大数据量测试
    fun getMassiveSchoolData(): JSValue {
        val schools = mutableListOf<School>()

        for (schoolIndex in 1..10) {
            val students = mutableListOf<Student>()
            val classes = mutableMapOf<String, List<Student>>()

            // 每个学校1000个学生
            for (i in 1..1000) {
                val student = Student(
                    name = "学生${schoolIndex}_$i",
                    age = 18 + (i % 5),
                    address = Address(
                        city = listOf("北京", "上海", "广州", "深圳")[i % 4],
                        street = "街道$i",
                        zipCode = "${100000 + i}"
                    ),
                    scores = List(10) { Random.nextDouble(60.0, 100.0) },
                    tags = mapOf(
                        "id" to "S${schoolIndex}_$i",
                        "grade" to "年级${(i % 4) + 1}",
                        "class" to "班级${(i % 20) + 1}"
                    )
                )
                students.add(student)

                val className = "Class_${(i % 50) + 1}"
                classes[className] = (classes[className] ?: emptyList()) + student
            }

            schools.add(
                School(
                    name = "学院$schoolIndex",
                    address = Address("城市$schoolIndex", "大街$schoolIndex", "${200000 + schoolIndex}"),
                    students = students,
                    classes = classes
                )
            )
        }

        return mapOf(
            "schoolCount" to schools.size,
            "totalStudents" to schools.sumOf { it.students.size },
            "schools" to schools
        ).toJSValue()
    }

//    // 测试3：双向复杂数据处理 - 接收Student并返回增强后的数据
//    fun processAndEnrichStudent(student: Student): JSValue {
//        // 计算GPA
//        val gpa = if (student.scores.isNotEmpty()) {
//            student.scores.average()
//        } else 0.0
//
//        // 添加计算后的标签
//        val enrichedTags = student.tags + mapOf(
//            "gpa" to String.format("%.2f", gpa),
//            "level" to when {
//                gpa >= 90 -> "优秀"
//                gpa >= 80 -> "良好"
//                gpa >= 70 -> "中等"
//                gpa >= 60 -> "及格"
//                else -> "不及格"
//            },
//            "processedAt" to System.currentTimeMillis().toString()
//        )
//
//        // 返回增强后的学生对象
//        val enrichedStudent = student.copy(
//            tags = enrichedTags
//        )
//
//        val analysisResult = AnalysisResult(
//            original = student,
//            enriched = enrichedStudent,
//            analysis = mapOf(
//                "gpa" to gpa,
//                "scoreCount" to student.scores.size,
//                "highestScore" to student.scores.maxOrNull(),
//                "lowestScore" to student.scores.minOrNull(),
//                "passRate" to "${student.scores.count { it >= 60 } * 100 / student.scores.size}%"
//            )
//        )
//
//        return analysisResult.toJSValue()
//    }
    // 传入 Int 返回 Int
    @OptIn(NativeRuntimeApi::class)
    override fun methodWithIntReturnInt(a: Int): Int {
        info("knoi-samplejsvalue methodWithIntReturnInt call info")
        logImpl?.callMethod<Unit>("info", "knoi-sample methodWithIntReturnInt logimpl")
        return a + 1
    }

    // 传入 Long 返回 Long
    override fun methodWithLongReturnLong(a: Long): Long {
        return a + 1
    }

    // 传入 Boolean 返回 Boolean
    override fun methodWithBooleanReturnBoolean(a: Boolean): Boolean {
        return !a
    }

    // 传入 Boolean 返回 Double
    override fun methodWithDoubleReturnDouble(a: Double): Double {
        return a + 0.1
    }

    // 传入 String 返回 String
    override fun methodWithStringReturnString(a: String): String {
        return a + " modify from KMM"
    }

    // 传入 回调 返回 回调
    @OptIn(ExperimentalForeignApi::class)
    override fun methodWithCallbackReturnCallback(a: (Array<JSValue>) -> Unit): ((Array<JSValue>) -> String) {
        a.invoke(arrayOf(JSValue(ktValueToJSValue(getEnv(), "test", String::class))))
        return {
            "callback result"
        }
    }

    // 传入 自定义回调 返回 自定义回调
    override fun methodWithCallbackReturnCallback2(
        a: (String, Int) -> Unit, b: String, c: Int
    ): ((String, Int) -> String) {
        a.invoke(b, c)
        return { name, age ->
            "callback result"
        }
    }

    // 传入 自定义回调 返回 String
    override fun methodWithCallbackReturnCallback3(
        a: (String, Int) -> String, b: (String, Int) -> String
    ): String {
        a.invoke("callback result", 42)
        b.invoke("callback result", 42)
        return "callback result"
    }

    // 传入 String 数组 返回 String数组
    override fun methodWithArrayStringReturnArrayString(a: Array<String>): Array<String> {
        val list = a.toMutableList()
        list.add("plus in KMM")
        return list.toTypedArray()
    }

    // 传入 JS 对象 返回 JS 对象
    override fun methodWithMapReturnMap(a: Map<String, Any?>): Map<String, Any?> {
        val map = a.toMutableMap()
        map.forEach {
            info("knoi-sample map ${it.key} ${it.value}")
        }
        map["kmm"] = "push in KMM"
        return a.toMap()
    }

    // 无参数调用
    override fun methodWithUnit() {
        info("TestServiceB methodWithUnit")
    }

    // 传入任意 JS 类型，返回任意 JS 类型
    override fun methodWithJSValueReturnJSValue(a: JSValue): JSValue {
        val arrayJSValue = a["array"]
        if (arrayJSValue != null) {
            val list = arrayJSValue.toList<String>()
            list?.forEach {
                info("TestServiceB methodWithJSValueReturnJSValue toList $it")
            }
        }
        return a["json"]!!
    }

    // 传入二进制数据返回二进制数据
    @OptIn(ExperimentalForeignApi::class)
    override fun methodWithArrayBufferReturnArrayBuffer(buffer: ArrayBuffer): ArrayBuffer {
        info("knoi-sample methodWithArrayBufferReturnArrayBuffer")
        val bufferArray = buffer.getData<uint8_tVar>()
        bufferArray?.set(4, 4u)
        bufferArray?.set(5, 5u)
        bufferArray?.set(6, 6u)
        bufferArray?.set(7, 7u)
        return buffer
    }

    // 多参数
    override fun method3Params(a: String, b: Int, c: JSValue): JSValue {
        return c
    }

    override fun methodWithMultiTypeMap(map: Map<String, Any?>): Map<String, Any?> {
        var arrayBuffer = map["arrayBuffer"] as ArrayBuffer
        var typedBuffer = map["typedBuffer"] as ArrayBuffer
        var function = map["callback"] as (Array<JSValue>) -> String
        var obj = map["object"] as Map<String, *>
        return map
    }

    override fun methodWithDefaultValueInSubType(a: Int, b: String) {
        info("knoi-sample methodWithDefaultValue $a $b")
    }

    fun methodWithDefaultValue(a: Int = 42, b: String = "default value") {
        info("knoi-sample methodWithDefaultValue $a $b")
    }

    // 隐藏方法，不生成到 d.ts
    @Hidden
    override fun method3(str: KClass<Any>): String {
        return "Hidden"
    }

    // private 方法，不生成到 d.ts
    private fun method4(str: KClass<Any>): String {
        return "Hidden"
    }

    fun testJSValueRef(jsValue: JSValue) {
        if (status) {
            info("knoi-sample testJSValueRef obtain JSValue")
            logImpl = jsValue["impl"]!!
            status = false
        } else {
            info("knoi-sample testJSValueRef release JSValue")
            logImpl = null
            status = true
        }
    }

}

//@OptIn(ExperimentalNativeApi::class)
//class Test1 {
//    val resource: Resource = Resource()
//
//    init {
////        createCleaner(resource) {
////            info("knoi-sample test clean. clean resource construct ${it.hashCode()}")
////        }
////        createCleaner(this) {
////            info("knoi-sample test clean. clean this construct ${it.hashCode()}")
////        }
//    }
//
//    private val clean = createCleaner(resource) {
//        info("knoi-sample test clean. clean resource ${it.hashCode()}")
//    }
////    private val clean1 = createCleaner(this) {
////        info("knoi-sample test clean. clean this ${it.hashCode()}")
////    }.freeze()
//}
//
//class Resource